home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / disk / misc / TurboDevice.lha / TurboDevice / Format.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-10-07  |  15.0 KB  |  547 lines

  1. /*
  2.   ##########################################################################
  3.   ####                                                                  ####
  4.   ####         TurboDevice - A resident RAM disk for the Amiga          ####
  5.   ####        =================================================         ####
  6.   ####                                                                  ####
  7.   #### Format.c                                                         ####
  8.   ####                                                                  ####
  9.   #### Version 1.00os  --  May 04, 1991                                 ####
  10.   ####                                                                  ####
  11.   #### Copyright (C) 1990  Thomas Dreibholz                             ####
  12.   ####               1991  Molbachweg 7                                 ####
  13.   ####                     51674 Wiehl/Germany                          ####
  14.   ####                     EMail: Dreibholz@bigfoot.com                 ####
  15.   ####                     WWW:   http://www.bigfoot.com/~dreibholz     ####
  16.   ####                                                                  ####
  17.   ##########################################################################
  18. */
  19. /***************************************************************************
  20.  *                                                                         *
  21.  *   This program is free software; you can redistribute it and/or modify  *
  22.  *   it under the terms of the GNU General Public License as published by  *
  23.  *   the Free Software Foundation; either version 2 of the License, or     *
  24.  *   (at your option) any later version.                                   *
  25.  *                                                                         *
  26.  ***************************************************************************/
  27.  
  28.  
  29. #include <exec/types.h>
  30. #include <libraries/dos.h>
  31. #include <libraries/dosextens.h>
  32. #include <libraries/filehandler.h>
  33. #include <exec/memory.h>
  34. #include <exec/execbase.h>
  35. #include <exec/resident.h>
  36. #include <exec/devices.h>
  37. #include <exec/io.h>
  38. #include <exec/libraries.h>
  39. #include <devices/trackdisk.h>
  40.  
  41. /* Resident-Informationen */
  42.  
  43. #define MODULENAME     "turbo.semaphore"
  44. #define IDSTRING       "turbo.semaphore 33.0 (1 Aug 1991)\n"
  45. #define TURBO_NUMUNITS 50
  46. #define TURBO_VERSION  33
  47. #define TURBO_PRIORITY 39
  48.  
  49. /* Interne Verwaltungsstrukturen */
  50.  
  51. struct MemoryPtr
  52. {
  53.  UBYTE *Address;
  54.  ULONG  Length;
  55. };
  56. struct TurboMod
  57. {
  58.  struct MemChunk  tm_OverwriteMe;
  59.  APTR             tm_ModuleTab[3];
  60.  struct Resident  tm_ROMTag;
  61.  struct MemoryPtr tm_MemoryPtr[TURBO_NUMUNITS];
  62.  struct MemList   tm_ML;
  63.  struct MemEntry  tm_NextList[TURBO_NUMUNITS];
  64.  UBYTE            tm_ModuleName[20];
  65.  UBYTE            tm_IdString[40];
  66. };
  67. struct MatchTag
  68. {
  69.  struct Resident  mt_ROMTag;
  70.  struct MemoryPtr mt_MemoryPtr[TURBO_NUMUNITS];
  71.  struct MemList   mt_ML;
  72.  struct MemEntry  mt_NextList[TURBO_NUMUNITS];
  73.  UBYTE            mt_ModuleName[20];
  74.  UBYTE            mt_IdString[40];
  75. };
  76. struct InfoTable
  77. {
  78.  struct DeviceNode        *DeviceNode;
  79.  struct FileSysStartupMsg *FSSM;
  80.  struct DosEnvec          *DosEnvec;
  81.  ULONG                     MemoryType;
  82.  struct DosLibrary        *DosBase;
  83. };
  84.  
  85. /* Hauptstruktur des Devices */
  86.  
  87. struct TurboDevice
  88. {
  89.  struct Library     Device;
  90.  struct ExecBase   *SysLib;
  91.  struct DosLibrary *DosLib;
  92.  APTR               SegList;
  93.  struct Resident   *Resident;
  94.  UBYTE              Flags;
  95.  UBYTE              DriveNum;
  96.  struct TurboUnit  *Units[TURBO_NUMUNITS];
  97. };
  98. struct TurboDevMsg
  99. {
  100.  struct Device     *tdm_Device;
  101.  struct Unit       *tdm_Unit;
  102. };
  103. struct TurboUnit
  104. {
  105.  struct Unit        tu_Unit;
  106.  UBYTE              tu_UnitNum;
  107.  UBYTE              tu_pad;
  108.  struct TurboDevMsg tu_Message;
  109.  struct Process    *tu_Process;
  110.  LONG               tu_LastComm;
  111.  ULONG              tu_Size;
  112.  ULONG              tu_NumTracks;
  113.  ULONG              tu_Position;
  114. };
  115.  
  116. /* Flags für MountList */
  117.  
  118. #define TDB_RAM 0L
  119. #define TDB_TYPE 1L
  120. #define TDF_RESIDENT 0L
  121. #define TDF_RAM (1L<<0)
  122. #define TDF_TYPE (1L<<1)
  123.  
  124. /* Berechnungsmacros */
  125.  
  126. #define DE(x) (info.DosEnvec->x)
  127. #define TRACKS (((DE(de_HighCyl)+1)-DE(de_LowCyl))*DE(de_Surfaces))
  128.  
  129. /* Funktionsvordefinitionen */
  130.  
  131. VOID   ResetProg();
  132. VOID   EndCode();
  133. UBYTE *GetMemory();
  134. ULONG  GetDriveSize();
  135. VOID RootBlockCheckSum();
  136. VOID AllocBitMapBlock();
  137. VOID FreeBitMapBlock();
  138. VOID CalcBitMapCheckSum();
  139. ULONG CalcRootBlock();
  140. ULONG CalcBitMap();
  141. ULONG CalcBlocks();
  142. VOID InstallRootBlock();
  143. VOID Format();
  144.  
  145. /* ================================================== */
  146. /* == GetMemory                                    == */
  147. /* == Beschafft und installiert Speicher           == */
  148. /* == Parameter:                                   == */
  149. /* ==   =>  EBase:    Zeiger auf ExecBase          == */
  150. /* ==   =>  Device:   Zeiger auf TurboDevice       == */
  151. /* ==   =>  Unit:     Unitnummer                   == */
  152. /* ==   =>  TurboUnit: Zeiger auf Unit             == */
  153. /* ==   <=  Kapazität des Units                    == */
  154. /* ================================================== */
  155.  
  156. UBYTE *GetMemory(EBase,Device,Unit,TurboUnit)
  157.  struct ExecBase *EBase;
  158.  struct TurboDevice *Device;
  159.  ULONG Unit;
  160.  struct TurboUnit *TurboUnit;
  161. {
  162.  register struct TurboMod *tm;
  163.  register struct Resident *res;
  164.  register struct MatchTag *mt;
  165.  UBYTE *copydest,*copysrc;
  166.  register UBYTE *mem;
  167.  register ULONG Size;
  168.  struct InfoTable info;
  169.  
  170.  info.DosBase=OpenLibrary("dos.library",0L);
  171.  res=FindResident(MODULENAME);
  172.  if(res==NULL) res=Device->Resident;
  173.  if(res!=NULL)
  174.   {
  175.    mt=(struct MatchTag *)res->rt_MatchTag;
  176.    mem=mt->mt_MemoryPtr[Unit].Address;
  177.    if(mem==NULL)
  178.     {
  179.      Size=GetDriveSize(FindTask(NULL),Unit,&info);
  180.      if(Size==NULL) return(NULL);
  181.      Size+=8;
  182.      mem=AllocMem(Size,info.MemoryType);
  183.      if(mem==NULL) return(NULL);
  184.      TurboUnit->tu_Size=Size-8;
  185.      TurboUnit->tu_NumTracks=TRACKS;
  186.      if(info.FSSM->fssm_Flags & TDF_RAM)
  187.       {
  188.        mem=mem+8;
  189.        Format(mem,&info,Device->DriveNum);
  190.        Device->DriveNum++;
  191.        return(mem);
  192.       }
  193.      mt->mt_MemoryPtr[Unit].Address=mem+8;
  194.      mt->mt_MemoryPtr[Unit].Length=Size-8;
  195.      mt->mt_ML.ml_ME[mt->mt_ML.ml_NumEntries].me_Addr=mem;
  196.      mt->mt_ML.ml_ME[mt->mt_ML.ml_NumEntries].me_Length=Size;
  197.      mt->mt_ML.ml_NumEntries++;
  198.      Forbid();
  199. #asm
  200.      movem.l d0/a6,-(sp)
  201.      move.l $4,a6
  202.      jsr -612(a6)
  203.      move.l d0,554(a6)
  204.      movem.l (sp)+,d0/a6
  205. #endasm
  206.      Permit();
  207.      mem=mem+8;
  208.      Format(mem,&info,Device->DriveNum);
  209.      Device->DriveNum++;
  210.     }
  211.    return(mem);
  212.   }
  213.  Size=GetDriveSize(FindTask(NULL),Unit,&info);
  214.  if(Size==NULL) return(NULL);
  215.  Size+=8;
  216.  mem=AllocMem(Size,info.MemoryType);
  217.  if(mem==NULL)
  218.   {
  219.    return(NULL);
  220.   }
  221.  TurboUnit->tu_Size=Size-8;
  222.  if(info.FSSM->fssm_Flags & TDF_RAM) return(mem+8);
  223.  tm=AllocMem(sizeof(struct TurboMod)+((ULONG)EndCode-(ULONG)ResetProg),MEMF_CHIP|MEMF_CLEAR|MEMF_PUBLIC);
  224.  if(tm==NULL)
  225.   {
  226.    Size-=8;
  227.    FreeMem(mem,Size);
  228.    return(NULL);
  229.   }
  230.  tm->tm_ROMTag.rt_MatchWord=RTC_MATCHWORD;
  231.  tm->tm_ROMTag.rt_MatchTag=&tm->tm_ROMTag;
  232.  tm->tm_ROMTag.rt_EndSkip=(APTR)((UBYTE *)tm+sizeof(struct TurboMod))+((ULONG)EndCode-(ULONG)ResetProg);
  233.  tm->tm_ROMTag.rt_Flags=RTF_COLDSTART;
  234.  tm->tm_ROMTag.rt_Version=TURBO_VERSION;
  235.  tm->tm_ROMTag.rt_Type=NT_SEMAPHORE;
  236.  tm->tm_ROMTag.rt_Pri=TURBO_PRIORITY;
  237.  tm->tm_ROMTag.rt_Name=tm->tm_ModuleName;
  238.  tm->tm_ROMTag.rt_IdString=tm->tm_IdString;
  239.  tm->tm_ROMTag.rt_Init=(APTR)((UBYTE *)tm+sizeof(struct TurboMod));
  240.  tm->tm_ML.ml_NumEntries=2;
  241.  tm->tm_ML.ml_Node.ln_Type=NT_MEMORY;
  242.  tm->tm_ML.ml_ME[0].me_Addr=(APTR)tm;
  243.  tm->tm_ML.ml_ME[0].me_Length=sizeof(struct TurboMod)+((ULONG)EndCode-(ULONG)ResetProg);
  244.  tm->tm_ML.ml_ME[1].me_Addr=mem;
  245.  tm->tm_ML.ml_ME[1].me_Length=Size;
  246.  tm->tm_MemoryPtr[Unit].Address=mem+8;
  247.  tm->tm_MemoryPtr[Unit].Length=Size-8;
  248.  strcpy(tm->tm_ModuleName,MODULENAME);
  249.  strcpy(tm->tm_IdString,IDSTRING);
  250.  copysrc=(UBYTE *)ResetProg;
  251.  copydest=(UBYTE *)tm->tm_ROMTag.rt_Init;
  252.  while(copysrc!=(UBYTE *)EndCode) *copydest++ = *copysrc++;
  253.  Device->Resident=&tm->tm_ROMTag;
  254.  Forbid();
  255.  tm->tm_ModuleTab[0]=(APTR)&tm->tm_ROMTag;
  256.  if(EBase->KickTagPtr)
  257.   {
  258.    tm->tm_ModuleTab[1]=(APTR)((ULONG)EBase->KickTagPtr|1<<31);
  259.   }
  260.  else
  261.   {
  262.    tm->tm_ModuleTab[1]=NULL;
  263.   }
  264.  if(EBase->KickMemPtr)
  265.   {
  266.    tm->tm_ML.ml_Node.ln_Succ=(struct Node *)EBase->KickMemPtr;
  267.   }
  268.  EBase->KickTagPtr=(APTR)tm->tm_ModuleTab;
  269.  EBase->KickMemPtr=(APTR)&tm->tm_ML;
  270. #asm
  271.  movem.l d0/a6,-(sp)
  272.  move.l $4,a6
  273.  jsr -612(a6)
  274.  move.l d0,554(a6)
  275.  movem.l (sp)+,d0/a6
  276. #endasm
  277.  Permit();
  278.  InitResident(&tm->tm_ROMTag,tm);
  279.  mem=mem+8;
  280.  Format(mem,&info,Device->DriveNum);
  281.  Device->DriveNum++;
  282.  return(mem);
  283. }
  284.  
  285. /* ================================================== */
  286. /* == ResetProg                                    == */
  287. /* == Diese Funktion läßt den Bildschirm für einen == */
  288. /* == kurzen Moment gelb werden, wenn das erste    == */
  289. /* == resetfeste Unit installiert wird und wenn    == */
  290. /* == ein resetfestes Unit bei einem Reset verfüg- == */
  291. /* == bar ist. Sollte trotz resetfestem Unit kein  == */
  292. /* == gelber Bildschirm auftreten, so wurden die   == */
  293. /* == Zeiger auf die resetfesten Strukturen        == */
  294. /* == zerstört! Die in den Units gespeicherten     == */
  295. /* == Daten sind Verloren!                         == */
  296. /* ================================================== */
  297.  
  298. /* Anfang des resetfesten Bereichs */
  299.  
  300. VOID ResetProg()
  301. {
  302. #asm
  303.    move.l d0,-(sp)         ; d0 retten
  304.    bset #1,$bfe001         ; Power-LED ausschalten
  305.    move.l #$10000,d0       ; $10000 nach d0
  306. 1$:                        ; Schleife
  307.    move.w #$0FF5,$DFF180   ; Farbe gelb in Farbregister 0
  308.    subq.l #1,d0            ; 1 von d0 abziehen
  309.    tst.l d0                ; Ist d0=0 ?
  310.    bne 1$                  ; Nein, dann zu Schleife
  311.    bclr #1,$bfe001         ; Power-LED einschalten
  312.    move.l (sp)+,d0         ; d0 freigeben
  313. #endasm
  314. }
  315.  
  316. /* Ende des resetfesten Bereichs */
  317.  
  318. VOID EndCode() {} /* Markierung für Ende des Bereichs */
  319.  
  320. /* ================================================== */
  321. /* == Format                                       == */
  322. /* == Diese Routine formatiert den belegten        == */
  323. /* == Speicher im AmigaDOS-Format. Sie wird nach   == */
  324. /* == jeder Belegung aufgerufen.                   == */
  325. /* ================================================== */
  326.  
  327. VOID Format(amem,info,number)
  328.  ULONG amem;
  329.  struct InfoTable *info;
  330.  ULONG number;
  331. {
  332.  REGISTER ULONG a,b,c,d;
  333.  REGISTER UBYTE *bmem;
  334.  REGISTER ULONG cmem;
  335.  UBYTE Name[15];
  336.  bmem=(UBYTE *)amem;
  337.  bmem[0]='D';
  338.  bmem[1]='O';
  339.  bmem[2]='S';
  340.  bmem[3]=0x00;
  341.  a=CalcRootBlock(info->DosEnvec);
  342.  b=CalcBitMap(info->DosEnvec);
  343.  cmem=amem+(a*512L);
  344.  strcpy(&Name,"Turbo #xy");
  345.  if(number>9)
  346.   {
  347.    c=number/10;
  348.    Name[7]=c+0x30;
  349.    c=number%10;
  350.    Name[8]=c+0x30;
  351.   }
  352.  else
  353.   {
  354.    Name[7]=number+0x30;
  355.    Name[8]=0x00;
  356.   }
  357.  InstallRootBlock(info->DosBase,cmem,&Name,b);
  358.  cmem=amem+(b*512);
  359.  d=CalcBlocks(info->DosEnvec);
  360.  for(c=2;c<=d;c++)
  361.   {
  362.    FreeBitMapBlock(c,cmem);
  363.   }
  364.  AllocBitMapBlock(a,cmem);
  365.  AllocBitMapBlock(b,cmem);
  366.  CalcBitMapCheckSum(cmem);
  367. }
  368.  
  369. /* ================================================== */
  370. /* == GetDriveSize                                 == */
  371. /* == Kapazität des Units ermitteln                == */
  372. /* == Parameter:                                   == */
  373. /* ==   => DosBase:  Zeiger auf DosLibrary         == */
  374. /* ==   => Task:     Zeiger auf Unit-Task          == */
  375. /* ==   => Unit:     Unitnummer                    == */
  376. /* ==   => Info:     Zeiger auf InfoTable          == */
  377. /* ==   <= Kapazität                               == */
  378. /* ================================================== */
  379.  
  380. ULONG GetDriveSize(task,unit,info)
  381.  ULONG task;
  382.  ULONG unit;
  383.  struct InfoTable *info;
  384. {
  385.  register struct DosBase *DosBase;
  386.  register struct DeviceNode *DeviceNode;
  387.  register struct RootNode *RootNode;
  388.  register struct DosInfo *DosInfo;
  389.  register struct FileSysStartupMsg *FSSM;
  390.  register struct DosEnvec *DosEnvec;
  391.  register ULONG size;
  392.  
  393.  DosBase=info->DosBase;
  394.  task=task+92;
  395.  size=64*1024*1024;
  396.  RootNode=DosBase->dl_Root;
  397.  DosInfo=BADDR(RootNode->rn_Info);
  398.  DeviceNode=BADDR(DosInfo->di_DevInfo);
  399.  do
  400.   {
  401.    if(DeviceNode->dn_Type==DLT_DEVICE)
  402.     {
  403.      if(DeviceNode->dn_Task==task)
  404.       {
  405.        FSSM=BADDR(DeviceNode->dn_Startup);
  406.        if(FSSM->fssm_Unit==unit)
  407.         {
  408.          DosEnvec=BADDR(FSSM->fssm_Environ);
  409.          size=(DosEnvec->de_HighCyl+1)-DosEnvec->de_LowCyl;
  410.          size=size*DosEnvec->de_BlocksPerTrack;
  411.          size=size*DosEnvec->de_Surfaces;
  412.          size=size*DosEnvec->de_SizeBlock*4;
  413.          size=size+(DosEnvec->de_Reserved*DosEnvec->de_SizeBlock*4);
  414.          size=size+(DosEnvec->de_PreAlloc*DosEnvec->de_SizeBlock*4);
  415.          info->DeviceNode=DeviceNode;
  416.          info->FSSM=FSSM;
  417.          info->DosEnvec=DosEnvec;
  418.          if(FSSM->fssm_Flags & TDF_TYPE)
  419.           {
  420.            switch(DosEnvec->de_BufMemType)
  421.             {
  422.              case 2:
  423.              case 3:
  424.               info->MemoryType=MEMF_CLEAR|MEMF_PUBLIC|MEMF_CHIP;
  425.               break;
  426.              case 4:
  427.              case 5:
  428.               info->MemoryType=MEMF_CLEAR|MEMF_PUBLIC|MEMF_FAST;
  429.               break;
  430.              default:
  431.               info->MemoryType=MEMF_CLEAR|MEMF_PUBLIC;
  432.               break;
  433.             }
  434.           } 
  435.          else
  436.           {
  437.            info->MemoryType=MEMF_CLEAR|MEMF_PUBLIC;
  438.           }
  439.          DeviceNode=NULL;
  440.         }
  441.        else
  442.         {
  443.          DeviceNode=BADDR(DeviceNode->dn_Next);
  444.         }
  445.       }
  446.      else
  447.       {
  448.        DeviceNode=BADDR(DeviceNode->dn_Next);
  449.       }
  450.     }
  451.    else
  452.     {
  453.      DeviceNode=BADDR(DeviceNode->dn_Next);
  454.     }
  455.   }
  456.  while(DeviceNode!=0L);
  457.  return(size);
  458. }
  459.  
  460. VOID RootBlockCheckSum(buf)
  461.  UBYTE *buf;
  462. {
  463.  ULONG checksum,*long_ptr;
  464.  LONG i;
  465.  long_ptr=(ULONG *)buf;
  466.  checksum=0;
  467.  for(i=0;i<TD_SECTOR/4;i++)
  468.   {
  469.    checksum+=long_ptr[i];
  470.   }
  471.  long_ptr[5]-=checksum;
  472. }
  473.  
  474. VOID InstallRootBlock(DBase,buf,diskname,bitmap)
  475.  struct DosLibrary *DBase;
  476.  UBYTE *buf;
  477.  UBYTE *diskname;
  478.  ULONG bitmap;
  479. {
  480.  ULONG *long_ptr;
  481.  LONG i;
  482.  long_ptr=(ULONG *)buf;
  483.  long_ptr[0]   =  2L;
  484.  long_ptr[3]   =  72L;
  485.  long_ptr[78]  = -1L;
  486.  long_ptr[79]  =  bitmap;
  487.  long_ptr[127] =  1L;
  488.  DateStamp(DBase,&long_ptr[121]);
  489.  DateStamp(DBase,&long_ptr[105]);
  490.  buf[432]=(UBYTE)strlen(diskname);
  491.  for(i=0;i<strlen(diskname);i++)
  492.   {
  493.    buf[433+i]=diskname[i];
  494.   }
  495.  RootBlockCheckSum(buf);
  496. }
  497.  
  498. ULONG CalcRootBlock(env)
  499.  struct DosEnvec *env;
  500. {
  501.  return((env->de_HighCyl+1)*env->de_Surfaces*env->de_BlocksPerTrack/2);
  502. }
  503.  
  504. ULONG CalcBitMap(env)
  505.  struct DosEnvec *env;
  506. {
  507.  return((CalcRootBlock(env)+1));
  508. }
  509.  
  510. ULONG CalcBlocks(env)
  511.  struct DosEnvec *env;
  512. {
  513.  return((env->de_HighCyl+1)*env->de_Surfaces*env->de_BlocksPerTrack-1);
  514.  
  515. VOID AllocBitMapBlock(block,buf)
  516.  LONG block;
  517.  UBYTE *buf;
  518. {
  519.  ULONG *long_ptr=(ULONG *)buf;
  520.  REGISTER LONG longword,bit;
  521.  longword=(block-2)/32;
  522.  bit=block-2-longword*32;
  523.  long_ptr[longword+1] &= (0xFFFFFFFF-(1L<<bit));
  524. }
  525.  
  526. VOID FreeBitMapBlock(block,buf)
  527.  LONG block;
  528.  UBYTE *buf;
  529. {
  530.  ULONG *long_ptr=(ULONG *)buf;
  531.  REGISTER LONG longword,bit;
  532.  longword=(block-2)/32;
  533.  bit=block-2-longword*32;
  534.  long_ptr[longword+1] |= (1L<<bit);
  535. }
  536.  
  537. VOID CalcBitMapCheckSum(buf)
  538.  UBYTE *buf;
  539. {
  540.  REGISTER ULONG checksum,i;
  541.  ULONG *long_ptr=(ULONG *)buf;
  542.  for(i=1,checksum=0;i<TD_SECTOR/4;i++) checksum+=long_ptr[i];
  543.  long_ptr[0]=-checksum;
  544. }
  545.  
  546.